package netengine;

import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey; 
import java.nio.channels.spi.AbstractSelector;
import java.util.Iterator;
import java.util.Set;

import main.Game;

import org.apache.log4j.Logger;

import thread.GameThread;

public class NetThread extends GameThread
{ 
	static Logger logger = Logger.getLogger(Game.class);
	
	public NetThread(AbstractSelector selector)
	{
		this.selector = selector;
	}
	
	public SelectionKey register(SelectableChannel channel, int ops, Object attachment)   
	{
		SelectionKey key = null;
		 
		try
		{ 
			key = channel.register(selector, ops, attachment);
		}
		catch (Exception exception)
		{
			logger.error("Excepiton: ", exception);
		}
		 
		return key;
	}
	
	public void doWork(long nowInMillis) 
	{
		try
		{ 
			selector.select(1);
			Set<SelectionKey> selectedKeys = selector.selectedKeys();
			  
			if (selectedKeys.size() == 0)
			{
				return;
			}
			
			Iterator<SelectionKey> it = selectedKeys.iterator();
			if (it.hasNext())
			{
				SelectionKey key = it.next();
				it.remove();
				
				if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT)
				{
					NetAcceptHandler acceptHandler = (NetAcceptHandler) key.attachment(); 
					acceptHandler.handleAccept();
				}
				
				if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ)
				{
					NetSocketHandler readHandler = (NetSocketHandler) key.attachment();
					readHandler.handleRead();
				}
				
				if ((key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE)
				{
					NetSocketHandler writeHandler = (NetSocketHandler) key.attachment();
					writeHandler.handleWrite();
				}
				
				if ((key.readyOps() & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT)
				{
					// Unsupported.
				}
			} 
		} 
		catch (Exception exception)
		{
			logger.error("Exception: ", exception);
		}
	}
 
	public String getThreadName() 
	{ 
		return "NetThread";
	}
 
	public int getTickInterval() 
	{ 
		return 100;
	}
	
	public AbstractSelector selector;
}
